﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Slaks.Graphs.GraphBuilder;
using Slaks.Graphs.Algorithms.DistanceAlgorithm;

namespace Slaks.Graphs.Algorithms
{    
	public class GraphDistanceMultiTypes: GraphDistanceBase
	{
		protected IList<GraphDistanceBase> _innerImpelemntations = new List<GraphDistanceBase>();
		public GraphDistanceMultiTypes () : base ()
        {
			InitInnetImplementors();
			IsVisible  = false;
        }
		protected virtual void InitInnetImplementors()
		{

		}
		public GraphDistanceMultiTypes(Graph one, Graph two):base(one,two)
		{
			IsVisible = false;
			InitInnetImplementors();
		}

		public override bool CanOperateOnRepresentation (BuilderType builderType)
		{
			return GetInnerImplementation(builderType) != null;
		}
        private GraphDistanceBase GetInnerImplementation(BuilderType builderType)
		{
			foreach (GraphDistanceBase graphDistance in _innerImpelemntations) {
				
				if(graphDistance.CanOperateOnRepresentation(builderType))
				{
					return graphDistance;
				}
			}
			return null;
		}
        public override double GetDistance()
        {
            var measure = GetInnerImplementation(firstGraph.GraphBuilderType);
            measure.firstGraph = this.one;
            measure.secondGraph = this.two;
			
           return measure.GetDistance();
        }
	}
	public class WGUMultiGraphDistance:GraphDistanceMultiTypes
	{
		
		public WGUMultiGraphDistance () : base ()
        {
			IsVisible  = true;
        }
		public WGUMultiGraphDistance(Graph one, Graph two):base(one,two)
		{
			IsVisible = true;
		}
				protected override void InitInnetImplementors ()
		{
			base.InitInnetImplementors ();
			var results = GetAvailableDistAlgorithms<MCSLimitedDistance>();
			foreach (var item in results) {
				_innerImpelemntations.Add(item);
			}
				
		}
	}
	public class MCSLimitedMultiDistance:GraphDistanceMultiTypes
	{
		
		public MCSLimitedMultiDistance () : base ()
        {
			IsVisible  = true;
        }
		protected override void InitInnetImplementors ()
		{
			base.InitInnetImplementors ();
			var results = GetAvailableDistAlgorithms<MCSLimitedDistance>();
			foreach (var item in results) {
				_innerImpelemntations.Add(item);
			}
				
		}
		public MCSLimitedMultiDistance(Graph one, Graph two):base(one,two)
		{
			IsVisible = true;
		}
	}
	public class WGUGraphDistance:GraphDistanceBase
	{
		public WGUGraphDistance():base(){}
		public WGUGraphDistance(Graph one, Graph two):base(one,two){}
	}
	public class MCSLimitedDistance:GraphDistanceBase
	{
				public MCSLimitedDistance():base(){}
		public MCSLimitedDistance(Graph one, Graph two):base(one,two){}

	}
}